﻿Imports Lucene.Net.Documents
Imports Lucene.Net.Search
Imports DotNetNuke.Services.Search
Imports Aricie.DNN.Modules.LuceneSearch.Settings
Imports Aricie.DNN.Services
Imports Aricie.Collections

Namespace Aricie.DNN.Modules.LuceneSearch.Business
    Public Class LuceneQueryResults
        Implements IDisposable


        Private Sub New()
        End Sub


        Public Sub New(ByVal queryDriver As PortalQueryingDriver, ByVal query As Query, ByVal searcher As Searcher, ByVal topDocs As TopDocs, ByVal startIndex As Integer, ByVal endIndex As Integer)
            Me._Query = query
            Me._Searcher = searcher
            Me._TopDocs = topDocs
            Me._StartIndex = startIndex
            Me._EndIndex = endIndex
        End Sub

        Private _Query As Query
        Private _Searcher As Searcher

        Private _TopDocs As TopDocs
        Private _FilteredNbResults As Integer = -1

        Private _StartIndex As Integer
        Private _EndIndex As Integer

        Private _SearchItemCollection As SearchResultsInfoCollection


        Public Property NbResults() As Integer
            Get
                If _FilteredNbResults > -1 Then
                    Return _FilteredNbResults
                End If
                If Me._TopDocs IsNot Nothing Then
                    Return Me._TopDocs.totalHits
                End If
                Return 0
            End Get
            Set(ByVal value As Integer)
                Me._FilteredNbResults = value
            End Set
        End Property


        Public Function AsSearchResultsCollection(ByVal searchModuleId As Integer, ByVal closeSearcher As Boolean) As SearchResultsInfoCollection
            If _SearchItemCollection Is Nothing Then
                _SearchItemCollection = New SearchResultsInfoCollection
                Dim objScoreDoc As ScoreDoc
                Dim objDoc As Document
                Dim objSearchResultsInfo As LuceneSearchResultsInfo
                Try
                    For i As Integer = _StartIndex To _EndIndex - 1
                        objScoreDoc = _TopDocs.scoreDocs(i)
                        objDoc = _Searcher.Doc(objScoreDoc.doc)
                        objSearchResultsInfo = New LuceneSearchResultsInfo(searchModuleId, _Query, objDoc, objScoreDoc)

                        _SearchItemCollection.Add(objSearchResultsInfo)
                    Next
                Catch ex As Exception
                    DotNetNuke.Services.Exceptions.Exceptions.LogException(ex)
                Finally
                    If closeSearcher Then
                        Me.Close()
                    End If
                End Try
            End If


            Return _SearchItemCollection
        End Function


        Protected Friend Sub ActionOnEachDocumentInResults(a As Action(Of Document), FieldsToLoad As SetBasedFieldSelector)
            If (a IsNot Nothing AndAlso _TopDocs IsNot Nothing) Then
                For i As Integer = _StartIndex To _EndIndex
                    Dim objScoreDoc As ScoreDoc = _TopDocs.scoreDocs(i)
                    a(_Searcher.Doc(objScoreDoc.doc, FieldsToLoad)) ' on lance l'action sur le document qui nous intéresse
                Next
            End If
        End Sub


        Private Shared _Empty As LuceneQueryResults
        Public Shared ReadOnly Property Empty() As LuceneQueryResults
            Get
                If _Empty Is Nothing Then
                    _Empty = New LuceneQueryResults
                End If
                Return _Empty
            End Get
        End Property

        Public Sub Close()
            If Me._Searcher IsNot Nothing Then
                Me._Searcher.Dispose()
            End If
        End Sub

#Region " IDisposable Support "

        Private disposedValue As Boolean = False        ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(ByVal disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    Try
                        Me.Close()
                    Catch ex As Exception
                        DotNetNuke.Services.Exceptions.Exceptions.LogException(ex)
                    End Try
                End If
            End If
            Me.disposedValue = True
        End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class
End Namespace